<?php
/**	
*	FILENAME: 		/libraries/newswire.php
*	DESCRIPTION:	This library that uses the PHP Snoopy library to obtain and parse the Wildcat Newswire.
*	AUTHOR:			Casey Burkhardt
*	VERSION:		1.0.0
*	LAST MODIFIED:	1/5/2010
**/

require_once($_SERVER['DOCUMENT_ROOT'] . "/config/environment.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/libraries/Snoopy.class.php");

// Define Constants
global $NEWSWIRE_URL, $HEADER_DATA;
$NEWSWIRE_URL = "http://unit.villanova.edu/mobile/newswire/wildcatnewswire/undergrad.html";
$HEADER_DATA = getHTTPRequestHeaders();

/**	
*	DESCRIPTION:	Obtains the timestamp of the current issue of the Wildcat Newswire
**/
function getNewswireTimestamp() {
	global $NEWSWIRE_URL, $HEADER_DATA;

	// We start by fetching the page containing the current issue of the Wildcat Newswire.
	// Create a new instance of Snoopy, the page fetching / parsing engine.
	$newswire = new Snoopy;
	
	// We can set a timeout, in case this thing doesn't work, but the Newswire server is unreliable, so we'll leave it be for now.
	// TODO: Determine if we need a timeout set here.
	//	$loginPage -> read_timeout = 5;
	
	// Set up appropriate HTTP header data.
	$newswire -> rawheaders = $HEADER_DATA;

	if ($newswire -> fetch($NEWSWIRE_URL)) {
		$searchQueryStart = "<td><i>Created: ";
		$searchQueryEnd = "</i></td>";
		$startIndex = strpos($newswire -> results, $searchQueryStart) + strlen($searchQueryStart);
		if ($startIndex === FALSE) {
			// The timestamp value could not be located on the page.
			return FALSE;
		} else {
			$endIndex = strpos($newswire -> results, $searchQueryEnd, $startIndex);
			$timestamp = trim(substr($newswire -> results, $startIndex, $endIndex - $startIndex));
			return $timestamp;
		}
	} else {
		// Downloading the remote page failed, return FALSE.
		return FALSE;
	}
}

/**	
*	DESCRIPTION:	Returns an array of all sections in the current Wildcat Newswire.
**/
function getNewswireSections() {
	global $NEWSWIRE_URL, $HEADER_DATA;
	
	// Set up Snoopy with the required parameters.
	$newswire = new Snoopy;
	$newswire -> rawheaders = $HEADER_DATA;

	if ($newswire -> fetch($NEWSWIRE_URL)) {
		// In order to obtain the section names, we'll extract all the text within '<b>' HTML tags.
		$headingTexts = array();
		$searchQueryStart = "<b>";
		$searchQueryEnd = "</b>";
		$startIndex = strpos($newswire -> results, $searchQueryStart);
		while ($startIndex !== FALSE) {
			$startIndex = $startIndex + strlen($searchQueryStart);
			$endIndex = strpos($newswire -> results, $searchQueryEnd, $startIndex);
			$headingTexts[] = trim(substr($newswire -> results, $startIndex, $endIndex - $startIndex));
			$startIndex = strpos($newswire -> results, $searchQueryStart, $endIndex + strlen($searchQueryEnd));
		}
	} else {
		// Downloading the remote page failed, return FALSE.
		return FALSE;
	}
	
	// We can now process the text in '<b>' HTML tags and determine which are section titles.
	if (count($headingTexts) === 0) {
		return FALSE;
	}
	
	// The first item in the array will repeat, one we find the first repetition, we know we've enumerated all the sections.
	$firstRepeat = FALSE;
	for($i = 1; $i < count($headingTexts); $i++) {
		if ($headingTexts[0] == $headingTexts[$i]) {
			$firstRepeat = $i;
			break;
		}
	}
	
	// Verify that we found a duplicate and slice the array of results.
	if ($firstRepeat === 0 || $firstRepeat === FALSE || $firstRepeat === (count($headingTexts) - 1)) {
		return FALSE;
	} else {
		$sections = array_slice($headingTexts, 0, $firstRepeat);
	}	
	return $sections;
}

/**	
*	DESCRIPTION:	Returns an array of story titles and their story ID values from the current Wildcat Newswire given a section name.
**/
function getStoryData($sectionName) {
	global $NEWSWIRE_URL, $HEADER_DATA;
	
	// Set up Snoopy with the required parameters.
	$newswire = new Snoopy;
	$newswire -> rawheaders = $HEADER_DATA;

	if ($newswire -> fetch($NEWSWIRE_URL)) {
		if(strlen($sectionName) == 0) {
			// List all stories.
			$sectionName = strtoupper($sectionName);
			$searchQueryStart = '<div class="type">';
			$searchQueryEnd = '<a name="0"></a>';
			$startIndex = strpos($newswire -> results, $searchQueryStart) + strlen($searchQueryStart);
			if ($startIndex === FALSE) {
				// Section heading could not be found on the fetched page.
				return FALSE;
			} else {
				$endIndex = strpos($newswire -> results, $searchQueryEnd, $startIndex);
				$dataBlock = trim(substr($newswire -> results, $startIndex, $endIndex - $startIndex));
			}			
		} else {
			// List only stories within the section heading.
			$sectionName = strtoupper($sectionName);
			$searchQueryStart = $sectionName;
			$searchQueryEnd = '<div class="type">';
			$startIndex = strpos($newswire -> results, $searchQueryStart) + strlen($searchQueryStart);
			if ($startIndex === FALSE) {
				// Section heading could not be found on the fetched page.
				return FALSE;
			} else {
				$endIndex = strpos($newswire -> results, $searchQueryEnd, $startIndex);
				$dataBlock = trim(substr($newswire -> results, $startIndex, $endIndex - $startIndex));
			}
		}
	} else {
		// Downloading the remote page failed, return FALSE.
		return FALSE;
	}
	
	// Begin parsing the results to extract story titles and story IDs.
	$storyData = array();
	$searchQueryStart = '<a href="#';
	$searchQueryEnd = '" target="_self">';
	$searchQueryTitleEnd = '</a>';
	$startIndex = strpos($dataBlock, $searchQueryStart);
	while ($startIndex !== FALSE) {
		// Search through the data block and extract the ID of a story.
		$startIndex = $startIndex + strlen($searchQueryStart);
		$endIndex = strpos($dataBlock, $searchQueryEnd, $startIndex);
		if ($endIndex === FALSE) {
			return FALSE;
		}
		$thisStory["id"] = trim(substr($dataBlock, $startIndex, $endIndex - $startIndex));
		// Adjust the position of the search and parse the story title.
		$startIndex = $endIndex + strlen($searchQueryEnd);
		$endIndex = strpos($dataBlock, $searchQueryTitleEnd, $startIndex);
		if ($endIndex === FALSE) {
			return FALSE;
		}
		$thisStory["title"] = trim(substr($dataBlock, $startIndex, $endIndex - $startIndex));
		// Add the story data to the result array.
		$storyData[] = $thisStory;
		// Reset the search for the next story item.
		$startIndex = strpos($dataBlock, $searchQueryStart, $endIndex + strlen($searchQueryTitleEnd));
	}	
	return $storyData;
}

/**	
*	DESCRIPTION:	Returns the title and body of a story from the current issue of the Wildcat Newswire given a story ID value.
**/
function getStory($storyID) {
	global $NEWSWIRE_URL, $HEADER_DATA;

	// Set up Snoopy with the required parameters.
	$newswire = new Snoopy;
	$newswire -> rawheaders = $HEADER_DATA;

	if ($newswire -> fetch($NEWSWIRE_URL)) {
		$searchQueryStart = '<a name="' . $storyID . '"></a>';
		$searchQueryEnd = '<div class="backtotop">';
		$startIndex = strpos($newswire -> results, $searchQueryStart);
		if ($startIndex === FALSE) {
			// The story ID could not be found.
			return FALSE;
		} else {
			$startIndex += strlen($searchQueryStart);
			$endIndex = strpos($newswire -> results, $searchQueryEnd, $startIndex);
			$dataBlock = trim(substr($newswire -> results, $startIndex, $endIndex - $startIndex));
		}	
	} else {
		// Downloading the remote page failed, return FALSE.
		return FALSE;
	}
	
	$story = array();
	// Extract the story title from the data block.
	$searchQueryStart = '<b>';
	$searchQueryStoryStart = '</div>';
	$searchQueryEnd = '</b>';
	$startIndex = strpos($dataBlock, $searchQueryStart) + strlen($searchQueryStart);
	if ($startIndex === FALSE) {
		// The story title could not be found.
		return FALSE;
	} else {
		$endIndex = strpos($dataBlock, $searchQueryEnd, $startIndex);
		$story["title"] = trim(substr($dataBlock, $startIndex, $endIndex - $startIndex));
		// Extract the HTML body of the story.
		$startIndex = strpos($dataBlock, $searchQueryStoryStart) + strlen($searchQueryStoryStart);
		if ($startIndex === FALSE) {
			return FALSE;
		}
		// Extract and strip the HTML from the story body.
		$story["body"] = trim($newswire -> _striptext(substr($dataBlock, $startIndex)));
	}
	return $story;
}
?>